#ifndef LIBSIM_RINGBUFFER_H_INCLUDED
#define LIBSIM_RINGBUFFER_H_INCLUDED

#include "keywords.h"
#include "allocator.h"
#include <stdint.h>
#include <stdbool.h>

LIBUTILS_STDC_BEGIN

LIBUTILS_CLASS(RingBuffer);

LIBUTILS_CLASS(RingBufferElement) {
    uintptr_t data;
};

LIBUTILS_CLASS(RingBufferVisitor) {
    void(*visit)(void *element, void *ctx);
    void *ctx;
};

RingBuffer *RingBufferCreate(uint32_t maxSize, const Allocator *allocator);
void RingBufferDestroy(RingBuffer *self);

const Allocator *RingBufferGetAllocator(const RingBuffer *self);

uint64_t RingBufferGetCapacity(const RingBuffer *self);
uint32_t RingBufferGetMaxSize(const RingBuffer *self);
uint32_t RingBufferGetSize(const RingBuffer *self);

bool RingBufferIsEmpty(const RingBuffer *self);
bool RingBufferIsFull(const RingBuffer *self);

bool RingBufferPush(RingBuffer *self, void *element);
bool RingBufferPop(RingBuffer *self, void **element);

void RingBufferClear(RingBuffer *self);

void RingBufferVisit(RingBuffer *self, const RingBufferVisitor *visitor);

LIBUTILS_STDC_END

#endif /* LIBSIM_RINGBUFFER_H_INCLUDED */
